This is not an exploit tutorial. This is just a simple walkthrough on writing exploits as modules for the metasploit framework. This document is tutorial style because we feel that example is the best way to learn how to write for Metasploit. These examples are really just a small look and what goes on and what is possible. The best way to learn more advanced capabilities is to read our module code, framework code, and email us with questions (in that order ;)). For example, if you are writing a brute force linux exploit, go through our exploits and find something similar. Not only will you be able to see how we did it, but you can also match our standard option names, techniques, etc. Let's start with a simple example of a network based buffer overflow. This is a simple daemon that will just listen for one connection, read it in, and exit. [ source code in vuln1.c ] You can see we have a buffer overflow when sending more than 64 characters of data. The strategy (since its a single shot), is to send a large nopsled, and to return directly into the stack. We'll start a new Metasploit exploit module, fill in the info information, and use some dev routines to find the offset to EIP. [ source code in vuln1_1.pm ] There are many comments inline in the exploit module. For our inital probing, we write a simple exploit without target or payload support. We just want to gather some inital information about the bug, and use this to write our exploit. We populate some metadata about the exploit, like the name, authors, supported architectures/operating systems, etc. We create out Exploit method, the code that will be called by the framework when the user chooses to execute your exploit modules. msf > use vuln1_1 msf vuln1_1 > show options Exploit Options =============== Exploit: Name Default Description -------- ------ ------- ------------------ required RHOST The target address required RPORT 11221 The target port Target: Targetless Exploit msf vuln1_1 > set RHOST 127.0.0.1 RHOST -> 127.0.0.1 msf vuln1_1 > exploit .... In another window .... Program received signal SIGSEGV, Segmentation fault. 0x63413563 in ?? () (gdb) # perl sdk/patternOffset.pl 0x63413563 76 We use the patternOffset.pl program to find the likely offset of EIP (76). We also used gdb to pull the value of esp (0xbffffa30) on our system. [ source code in vuln1_2.pm ] We know got enough information about the bug to actually start writing an Exploit. We add a Target (just one for my system), and also require the Framework to supply use with a payload. We can us this information and actually write a functional exploit (for our system). We add a Payload entry, telling that Framework to require the user to supply a payload, and allowing us to pull out this payload from the EncodedPayload entry the Framework setups up in the environment. EncodedPayload is an object, and we simple call to the Payload method. We setup some Advanced options for some of the details of our exploit vector. This is handy mostly for development, or other researcher thinkering with your exploits. These aren't options that a general user will usually change, but I've found that adding options like these is be very useful. It is important to note that you call GetLocal for Advanced Options! The general rule of thumb is to call GetLocal for Advanced Options, and GetVar for everything else. One main difference between that two is that GetLocal will not look in the Global Environment (not entirely true, but enough so). We finish the module, and it works! msf vuln1_2(linx86_reverse) > show options Exploit and Payload Options =========================== Exploit: Name Default Description -------- ------ --------- ------------------ required RHOST 127.0.0.1 The target address required RPORT 11221 The target port Payload: Name Default Description -------- ------ --------- ----------------------------------- required LHOST 127.0.0.1 Local address to receive connection required LPORT 12322 Local port to receive connection Target: Slackware Linux msf vuln1_2(linx86_reverse) > set LHOST: 127.0.0.1 LPORT: 12322 PAYLOAD: linx86_reverse RHOST: 127.0.0.1 TARGET: 0 msf vuln1_2(linx86_reverse) > exploit [*] Starting Reverse Handler. [*] Got connection from 127.0.0.1:32896 id uid=1000(spoonm) gid=1000(spoonm) groups=1000(spoonm) [ source code in vuln1_3.pm ] This exploitable program will have the socket open when we gain execution control. This allows us to support findsock payloads, allowing reuse of the inital connection we made to the service. We inform the Framework that we support payloads tagged with the findsock keyword, adding it to our list of supported payload keys (with the +findsock). Along with supporting findsock, we also must pull the CPORT option out of the environment. CPORT is used by srcport style findsock payloads, enabling the exploit and payloads to both have knowledge of the srcport the connection will be made from (used to identify the socket in the shellcode). The CPORT option is added into UserOpts by the Payload, and is only neccessarily from the users end when using a srcport style findsock payload. From the exploit perspective you must be aware that this option may be set, and pass it along to the socket creation method, creating the socket with the specified srcport (if supplied). If a user isn't using a srcport style findsock payload, CPORT will be undefined and the socket will get created with a random source port. Keeping srcport in mind is very important, sometimes it is required to sleep a little between brute force attemps to allow the old socket to get cleaned up so you can reuse the src port. It is also important to realize that you can not have multiple concurrent connections with the same srcport, so CPORT should only be passed on the connection likely to have the shell (if say, you had an exploit that required more than one connection to be made). We add some general nice features to the exploit, printing information about what target it is trying, informing the user that things are working. Below is a demonstration of working findsock (recv tag style, not CPORT). msf vuln1_3(linx86_findrecv) > show options Exploit and Payload Options =========================== Exploit: Name Default Description -------- ------ --------- ------------------ required RHOST 127.0.0.1 The target address required RPORT 11221 The target port Payload: Name Default Description -------- ------ ------- ----------- Target: Slackware Linux msf vuln1_3(linx86_findrecv) > set PAYLOAD: linx86_findrecv RHOST: 127.0.0.1 TARGET: 0 msf vuln1_3(linx86_findrecv) > exploit Trying Slackware Linux - 0xbffffa60 [*] Findsock found shell... id uid=1000(spoonm) gid=1000(spoonm) groups=1000(spoonm) Instead of writing a more complicated demonstration vulnerable program (like one that does a fork), I documented the svnserve_date module. This module exploits the subversion svnserve daemon, and demonstrates a bruteforce exploit with box linux and freebsd targets, and findsock support. [ source code in svnserve_date.pm ] This document should be enough to get your feet off the ground and familiar with the development side of the Metasploit Framework. The requirements for exploits very greatly and often require specific features and support from the Framework. We've written a lot of different modules that take advantage of different pieces of the framework, and suggest reading these to become a more advanced module developer. Thank you for not smoking, and enjoy your day.